import { getChatToken } from '@/apis/chat'
import { ElLoading } from 'element-plus'
import { setItem } from '@/utils/stroge'

class WebSocketWithHeartbeat {
  constructor(getMessageCallBack) {
    // 心跳请求间隔
    this.heartbeatInterval = 50000;
    this.websocket = null;
    this.heartbeatTimer = null;
    // 获取消息的回调函数
    this.getMessage = getMessageCallBack
    // 重连间隔时间，单位为毫秒
    this.reconnectInterval = 3000
    this.reconnectTimer = null;
    // 未发出去的消息
    this.UnsentMessages = null
  }

  async connect(cb) {
    const { data } = await getChatToken()
    setItem('chatToken', data)
    const time = Date.now()
    const url = `wss://llm.yunzhangfang.com/websocket/5AD942B55FA81DB3/${data}/${time}`
    this.websocket = new WebSocket(url);

    this.websocket.onopen = () => {
      console.log('WebSocket连接已打开');
      this.startHeartbeat();
      clearTimeout(this.reconnectTimer);
      cb && cb()
      if(this.UnsentMessages){
        this.send(this.UnsentMessages)
        this.UnsentMessages = null
      }
    };

    this.websocket.onmessage = (event) => {
      const data = JSON.parse(event.data)
      if(data.type === 'error'){
        // 发生错误，token过期，以及其他原因
        this.stopHeartbeat();
        this.reconnect();
      }else{
        this.getMessage(event.data)
        this.resetHeartbeat()
      }
    };

    this.websocket.onclose = () => {
      console.log('WebSocket连接已关闭');
      this.stopHeartbeat();
    };

    this.websocket.onerror = (error) => {
      console.error('WebSocket发生错误:', error);
      this.stopHeartbeat();
    };
  }

  send(message) {
    if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
      this.websocket.send(JSON.stringify(message));
    } else {
      // 如果发送消息后，发现链接未打开，
      // 需要判断此次发送的是正常请求还是心跳请求
      if(message.prompt !== 'ping'){
        // 只有不是心跳请求的情况下才记录未发送的消息，以及触发重连机制
        this.UnsentMessages = message
        this.reconnect();
      }
      this.stopHeartbeat();
      console.log('WebSocket连接未打开');
    }
  }

  // 开始心跳请求
  startHeartbeat() {
    this.send({
      prompt:'ping',
      type:'ping'
    })

    // 清除之前的定时器
    clearTimeout(this.heartbeatTimer);

    // 重新设置定时器，40秒后再次发送心跳请求
    this.heartbeatTimer = setTimeout(this.startHeartbeat.bind(this), this.heartbeatInterval)
  }

  // 停止心跳请求
  stopHeartbeat() {
    clearTimeout(this.heartbeatTimer);
  }

  // 打断心跳请求倒计时，重新对心跳请求计时
  resetHeartbeat(){
    // 清除之前的定时器
    clearTimeout(this.heartbeatTimer);

    // 重新设置定时器，40秒后再次发送心跳请求
    this.heartbeatTimer = setTimeout(this.startHeartbeat.bind(this), this.heartbeatInterval)
  }
  
  close() {
    if (this.websocket) {
      this.websocket.close();
    }
  }

  // 重连机制
  reconnect() {
    if (this.reconnectTimer) return
    this.reconnectTimer = window.setTimeout(() => {
      this.connect();
      this.reconnectTimer = null;
    }, this.reconnectInterval);
  }
}

export default WebSocketWithHeartbeat
